package com.kasax.plugin.app.transform

import com.android.build.api.transform.*
import com.android.build.gradle.internal.pipeline.TransformManager
import com.android.utils.FileUtils
import com.kasax.plugin.app.LogUtils

/**
 * https://mp.weixin.qq.com/s/JqJuKwrbriJ-4Hn14KMS4A
 */
class MyCustomTransform extends Transform {
    /**
     * 设置我们自定义 Transform 对应的 Task 名称，Gradle 在编译的时候，会将这个名称经过一些拼接显示在控制台上
     */
    @Override
    String getName() {
        return "MyCustomTransform"
    }

    /**
     * 项目中会有各种各样格式的文件，该方法可以设置 Transform 接收的文件类型
     * 具体取值范围：
     * CONTENT_CLASS：Java 字节码文件，
     * CONTENT_JARS：jar 包
     * CONTENT_RESOURCES：资源，包含 java 文件
     * CONTENT_DEX：dex 文件
     * CONTENT_DEX_WITH_RESOURCES：包含资源的 dex 文件
     *
     * 我们能用的就两种：CONTENT_CLASS 和 CONTENT_JARS
     * 其余几种仅 AGP 可用
     */
    @Override
    Set<QualifiedContent.ContentType> getInputTypes() {
        return TransformManager.CONTENT_CLASS
    }

    /**
     * 定义 Transform 检索的范围：
     * PROJECT：只检索项目内容
     * SUB_PROJECTS：只检索子项目内容
     * EXTERNAL_LIBRARIES：只检索外部库，包括当前模块和子模块本地依赖和远程依赖的 JAR/AAR
     * TESTED_CODE：由当前变体所测试的代码（包括依赖项）
     * PROVIDED_ONLY：本地依赖和远程依赖的 JAR/AAR（provided-only）
     */
    @Override
    Set<? super QualifiedContent.Scope> getScopes() {
        return TransformManager.SCOPE_FULL_PROJECT
    }

    /**
     * 表示当前 Transform 是否支持增量编译 true：支持 false：不支持
     */
    @Override
    boolean isIncremental() {
        return false
    }

    /**
     * 进行具体的检索操作
     */
    @Override
    void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
        super.transform(transformInvocation)

        LogUtils.d(getName(), "------------ ------------  transform 开始  ------------ ------------  ")
        def inputs = transformInvocation.inputs
        def outputsProvider = transformInvocation.outputProvider
        inputs.each { TransformInput input ->
            // 一、输入源为文件夹类型
            input.directoryInputs.forEach { DirectoryInput directoryInput ->
                //1、TODO 针对文件夹进行字节码操作，这个地方我们就可以做一些狸猫换太子，偷天换日的事情了
                //先对字节码进行修改，在复制给 dest

                //2、构建输出路径 dest
                def dest = outputsProvider.getContentLocation(
                        directoryInput.name,
                        directoryInput.contentTypes,
                        directoryInput.scopes,
                        Format.DIRECTORY
                )
                //3、将文件夹复制给 dest ，dest 将会传递给下一个 Transform
                FileUtils.copyDirectoryToDirectory(directoryInput.file, dest)
            }

            // 二、输入源为jar包类型
            input.jarInputs.forEach { JarInput jarInput ->
                //1、TODO 针对 jar 包进行相关处理


                //2、构建输出路径 dest
                def dest = outputsProvider.getContentLocation(
                        jarInput.name,
                        jarInput.contentTypes,
                        jarInput.scopes,
                        Format.JAR
                )
                //3、将 jar 包复制给 dest，dest 将会传递给下一个 Transform
                FileUtils.copyFile(jarInput.file, dest)
            }
        }

        LogUtils.d(getName(), "------------ ------------  transform 结束  ------------ ------------  ")
    }
}